use std::path::Path;
use crate::{
    error::ServerError, prelude::now_str, protocol::data_schema::DataTrait, tasks::task::Task, workflows::{manager::WORKFLOW_MANAGER, workflow::{RunningWorkflow, Workflow}}
};

#[derive(Debug, serde::Serialize)]
pub struct WorkflowFileMeta<'out> {
    pub port: u16,
    pub name: &'out str,
    pub status: &'out crate::workflows::workflow::WorkflowRunningStatus,
    pub progress: Vec<(&'out str, u64)>,
    pub created_at: u64,
    pub completed_at: Option<u64>,
}

impl<'out> WorkflowFileMeta<'out> {
    pub fn from_running_workflow(workflow: &'out RunningWorkflow) -> Self {
        Self { 
            port: workflow.port, 
            name: &workflow.name, 
            status: &workflow.status, 
            progress: workflow.progress.iter().map(|(name, time)| (name.as_str(), *time)).collect(), 
            created_at: workflow.created_at, 
            completed_at: workflow.completed_at 
        }
    }
}

pub struct WorkflowFile {
    base_dir: String,
}

impl WorkflowFile {
    pub fn new() -> Self {
        Self { base_dir: "./edp_files/workflows".to_string() }
    }
    pub fn save_workflow(&self, workflow: &RunningWorkflow) -> Result<(), ServerError> {
        let workflow_name = &workflow.name;
        let workflow_name_full = format!("{}-{}", workflow_name, now_str());
        let workflow_dir = format!("{}/{}/{}", self.base_dir, workflow_name, now_str());
        std::fs::create_dir_all(&workflow_dir).map_err(|e| ServerError::LogFileError(e.to_string()))?;
        let workflow_dir = Path::new(&workflow_dir);
        let meta_file = workflow_dir.join("meta.json");
        let meta_str = serde_json::to_string_pretty(&WorkflowFileMeta::from_running_workflow(workflow)).map_err(|e| ServerError::LogFileError(e.to_string()))?;
        std::fs::write(meta_file, meta_str).map_err(|e| ServerError::LogFileError(e.to_string()))?;
        let workflow_file = workflow_dir.join("result.json");
        let manager = WORKFLOW_MANAGER.get().unwrap().lock().unwrap();
        let result = manager.get_running_workflow_result(workflow.port);
        match result {
            Some(Ok(result)) => {
                let json_str = serde_json::to_string_pretty(&result.to_json_less()).map_err(|e| ServerError::LogFileError(e.to_string()))?;
                std::fs::write(workflow_file, json_str).map_err(|e| ServerError::LogFileError(e.to_string()))?;
            }
            Some(Err(e)) => {
                let json_str = serde_json::to_string_pretty(&e).map_err(|e| ServerError::LogFileError(e.to_string()))?;
                std::fs::write(workflow_file, json_str).map_err(|e| ServerError::LogFileError(e.to_string()))?;
            }
            None => {
                println!("工作流无结果: {}", workflow_name_full);
            }
        }
        drop(manager);
        Ok(())
    }
}
